<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
    <script src="/dist/alpine.js" defer></script>
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
</head>

<body>
    <!-- Memory Game -->
    <div x-data="game()" class="px-10 flex items-center justify-center min-h-screen">
        <h1 class="fixed top-0 right-0 p-10 font-bold text-3xl">
            <span x-text="points"></span>
            <span class="text-xs">pts</span>
        </h1>

        <div class="flex-1 grid grid-cols-4 gap-10">
            <template x-for="(card, index) in cards" :key="index">
                <div>
                    <button x-show="! card.cleared"
                            :style="'background: ' + (card.flipped ? card.color : '#999')"
                            :disabled="flippedCards.length >= 2"
                            class="w-full h-32"
                            @click="flipCard(card)"
                    >
                    </button>
                </div>
            </template>
        </div>
    </div>

    <!-- Flash Message -->
    <div x-data="{ show: false, message: '' }"
         x-show.transition.opacity="show"
         x-text="message"
         @flash.window="
            message = $event.detail.message;
            show = true;
            setTimeout(() => show = false, 1000)
        "
         class="fixed bottom-0 right-0 bg-green-500 text-white p-2 mb-4 mr-4 rounded"
    >
    </div>

    <script>
        function pause(milliseconds = 1000) {
            return new Promise(resolve => setTimeout(resolve, milliseconds));
        }

        function flash(message) {
            window.dispatchEvent(new CustomEvent('flash', {
                detail: { message }
            }));
        }

        function game() {
            return {
                cards: [
                    { color: 'green', flipped: false, cleared: false },
                    { color: 'red', flipped: false, cleared: false },
                    { color: 'blue', flipped: false, cleared: false },
                    { color: 'yellow', flipped: false, cleared: false },
                    { color: 'green', flipped: false, cleared: false },
                    { color: 'red', flipped: false, cleared: false },
                    { color: 'blue', flipped: false, cleared: false },
                    { color: 'yellow', flipped: false, cleared: false },
                ].sort(() => Math.random() - .5),

                get flippedCards() {
                    return this.cards.filter(card => card.flipped);
                },

                get clearedCards() {
                    return this.cards.filter(card => card.cleared);
                },

                get remainingCards() {
                    return this.cards.filter(card => ! card.cleared);
                },

                get points() {
                    return this.clearedCards.length;
                },

                async flipCard(card) {
                    card.flipped = ! card.flipped;

                    if (this.flippedCards.length !== 2) return;

                    if (this.hasMatch()) {
                        flash('You found a match!');

                        await pause();

                        this.flippedCards.forEach(card => card.cleared = true);

                        if (! this.remainingCards.length) {
                            alert('You Won!');
                        }
                    } else {
                        await pause();
                    }

                    this.flippedCards.forEach(card => card.flipped = false);
                },

                hasMatch() {
                    return this.flippedCards[0]['color'] === this.flippedCards[1]['color'];
                }
            };
        }
    </script>
</body>
</html>
